package org.bigjava.novelplatform.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.bigjava.novelplatform.common.exception.UserActionException;
import org.bigjava.novelplatform.common.utils.RedisBuildKey;
import org.bigjava.novelplatform.common.utils.RedisUtils;
import org.bigjava.novelplatform.service.RabbitmqService;
import org.bigjava.novelplatform.vo.ReleaseVo;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalTime;
import java.util.Date;

import static org.bigjava.novelplatform.common.exception.ExceptionCodeMessage.UNRECOGNIZED_TYPE;

/**
 * @author ykh
 * @create 2022-05-13 16:28
 */
@Slf4j
@Service
public class RabbitmqServiceImpl implements RabbitmqService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Resource
    private RedisUtils redisUtils;

    @Override
    public void timedTask(ReleaseVo releaseVo) {
        //当前时间
        LocalTime start = LocalTime.now();
        Duration between = Duration.between(start, releaseVo.getReleaseTime());
        long nanos = between.toMillis();
        //
//        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
//        Date start;
//        long nanos = 0;
//        try {
//            start= format.parse(format.format(new Date()));
//            nanos = releaseVo.getReleaseTime().getTime()-start.getTime();
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//        //
        Integer timeout;
        //当前时间>选中时间
        if (nanos < 0){
            timeout =  24*60*60*1000 + (int) nanos;
        }else{
            timeout = Math.toIntExact(nanos);
        }
        switch (releaseVo.getReleaseCycle()) {
            //仅此一次
            case "1":
                //将vo放置到redis中，当队列中延迟结束后查看redis中的vo是否存在，存在执行任务，不存在放弃执行
                onlyOne(releaseVo,timeout);
                break;
            //每天
            case "2":
                continued(releaseVo,timeout);
                break;
            default:
                throw new UserActionException(UNRECOGNIZED_TYPE);
        }
    }

    public void onlyOne(ReleaseVo releaseVo,Integer timeOut) {
        log.info("onlyOne发送消息{}",releaseVo);
        try {
            //在redis存储定时任务信息,允许五分钟的延迟
            redisUtils.set(releaseVo, RedisBuildKey.bindTimedTask(releaseVo.getBookId()),
                    Duration.ofMillis(timeOut).plusMillis(1000*60*5));
            rabbitTemplate.convertAndSend("delayed_exchange", "onlyOne", releaseVo, (msg -> {
                //持久化
                //msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);//默认持久化
                //超时时间
                msg.getMessageProperties().setDelay(timeOut);
                return msg;
            }), new CorrelationData());
        } catch (AmqpException e) {
            log.warn("onlyOne消息{}发送失败", releaseVo);
            throw new RuntimeException(e);
        }
    }


    public void continued(ReleaseVo releaseVo,Integer timeOut) {
        log.info("continued发送消息{}",releaseVo);
        //在redis存储定时任务信息,无过期时间
        redisUtils.set(releaseVo, RedisBuildKey.bindTimedTask(releaseVo.getBookId()),null);
        try {
            rabbitTemplate.convertAndSend("delayed_exchange", "continued", releaseVo, (msg -> {
                //持久化
                //msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);//默认持久化
                //超时时间
                msg.getMessageProperties().setDelay(timeOut);
                return msg;
            }), new CorrelationData());
        } catch (AmqpException e) {
            log.warn("continued消息{}发送失败", releaseVo);
            throw new RuntimeException(e);
        }
    }
}
